using JQData.Application.Helper;
using JQData.Core;
using JQData.Core.DataModel;
using JQData.Core.DbModel;
using JQData.Core.TushareSDK;
using Microsoft.Extensions.Caching.Distributed;
using System.Dynamic;
using System.Security.Cryptography.Xml;
using System.Text.Json;



namespace JQData.Application.DataFetch
{
    public class HotMoneyStockDataFetch(
        IRepository<HotMoney> _hmDb,
        IRepository<HotMoneyTrade> _hmtDb,
        IRepository<HotMoneyStockCycleProfit> _hmscpDb,
        IRepository<StockBasic> _sbDb,
        IDistributedCache _distributedCache,
        HotMoneyDataFetch _hotMoneyDataFetch
        ) : DataFetchBase(_hmDb, _hmtDb, _hmscpDb, _sbDb)
    {
        public HotMoneyData Data { get; set; } = new();



        public async Task<List<StockHotMoneyData>> Load(bool isCache = true)
        {
            var cacheKey = DataCacheManage.GetCacheKey(CacheKeyType.StockHotMoneyData, null);
            if (isCache)
            {
                var cachedData = await _distributedCache.GetStringAsync(cacheKey);
                if (!string.IsNullOrEmpty(cachedData))
                {
                    return JsonSerializer.Deserialize<List<StockHotMoneyData>>(cachedData);
                }
            }




            //所有游资
            var list = await _hmDb.Entities.ToListAsync();
            var hotMoneyDataList = new List<HotMoneyData>();
            foreach (var item in list)
            {
                var li = await _hotMoneyDataFetch.GetHotMoneyData(item.Id);
                hotMoneyDataList.Add(li);
            }

            // 聚合为按股票汇总的数据
            var resDict = new Dictionary<int, StockHotMoneyData>();

            // 统计30日内的持仓与买卖金额
            foreach (var hm in hotMoneyDataList)
            {
                foreach (var s in hm.Day30)
                {
                    if (!resDict.TryGetValue(s.StockId, out var entry))
                    {
                        entry = new StockHotMoneyData
                        {
                            StockId = s.StockId,
                            StockCode = s.DbStock?.TsCode,
                            StockName = s.StockName ?? s.DbStock?.Name,
                            FirstBuyData = s.BuyDate
                        };
                        resDict[s.StockId] = entry;
                    }

                    if (s.BuyDate < entry.FirstBuyData)
                    {
                        entry.FirstBuyData = s.BuyDate;
                    }


                    // 有该游资近30日持仓则计数+1
                    entry.HotMoneyCount30Day += 1;

                    var buyAmt = s.BuyInfo?.Sum(b => b.Amount) ?? 0m;
                    var sellAmt = s.SellInfo?.Sum(b => b.Amount) ?? 0m;

                    entry.BuyAmount += buyAmt;
                    entry.SellAmount += sellAmt;

                    // 以近30日交易后剩余仓位估算持仓市值与浮盈
                    var holdingValue = s.RemainingPosition * s.CurrentPrice;
                    entry.Price += holdingValue;

                    var win = (s.CurrentPrice - s.CostPrice) * s.RemainingPosition;
                    entry.WinPrice += win;
                }
            }

            // 统计7日内加仓/清仓，正数表示加仓的游资更多，负数表示清仓游资更多
            foreach (var hm in hotMoneyDataList)
            {
                foreach (var s in hm.Day7)
                {
                    if (!resDict.TryGetValue(s.StockId, out var entry))
                    {
                        entry = new StockHotMoneyData
                        {
                            StockId = s.StockId,
                            StockName = s.StockName ?? s.DbStock?.Name
                        };
                        resDict[s.StockId] = entry;
                    }

                    var netVol7 = (s.BuyInfo?.Sum(i => i.Vol) ?? 0m) - (s.SellInfo?.Sum(i => i.Vol) ?? 0m);
                    if (netVol7 > 0)
                        entry.HotMoneyCount7DayAdd += 1; // 有加仓
                    else if (netVol7 < 0)
                        entry.HotMoneyCount7DayAdd -= 1; // 有减仓/清仓
                }
            }

            // 根据7日内加减仓情况给出持仓状态
            foreach (var kv in resDict)
            {
                var e = kv.Value;
                if (e.HotMoneyCount7DayAdd > 0) e.HoldState = HoldState.多头共识;
                else if (e.HotMoneyCount7DayAdd < 0) e.HoldState = HoldState.多数了结;
                else e.HoldState = HoldState.新上榜;
            }

            var res = resDict.Values
                .OrderByDescending(i => i.NetBuyAmount)
                .ToList();

            //如果使用缓存，则添加缓存
            if (isCache)
            {
                await DataCacheManage.AddCache(_distributedCache, cacheKey, res);
            }


            return res;
        }
    }

    /// <summary>
    /// 股票游资信息
    /// </summary>
    public class StockHotMoneyData
    {
        public int StockId { get; set; }

        public string StockCode { get; set; }

        public string StockName { get; set; }

        /// <summary>
        /// 游资持有数量（30天）
        /// </summary>
        public int HotMoneyCount30Day { get; set; }

        /// <summary>
        /// 7日内游资加仓/清仓数量
        /// </summary>
        public int HotMoneyCount7DayAdd { get; set; }

        /// <summary>
        /// 持仓总额
        /// </summary>
        public decimal Price { get; set; }


        /// <summary>
        /// 持仓总浮盈 
        /// </summary>
        public decimal WinPrice { get; set; }

        /// <summary>
        /// 买入金额
        /// </summary>
        public decimal BuyAmount { get; set; }
        /// <summary>
        /// 卖出金额
        /// </summary>
        public decimal SellAmount { get; set; }

        /// <summary>
        /// 净买入金额
        /// </summary>
        public decimal NetBuyAmount => BuyAmount - SellAmount;


        public DateOnly FirstBuyData { get; set; }


        /// <summary>
        /// 
        /// </summary>
        public HoldState HoldState { get; set; }


    }

    public enum HoldState
    {
        /// <summary>
        /// 持有和新增比较多
        /// </summary>
        多头共识,
        /// <summary>
        /// 7日内大多数人清仓
        /// </summary>
        多数了结,
        /// <summary>
        /// 7日大多数人持有
        /// </summary>
        新上榜
    }

}
